/* $Header: run_task.c,v 2.2 01/10/02 10:32:34 przybyls Exp $ */

/***********************************************************************/
/*                                                                     */
/*                  Copyright Hewlett-Packard Co. 1991,1992            */
/*                                                                     */
/***********************************************************************/

/***********************************************************************/
/* MODULE NAME: run task                                               */
/* ============                                                        */
/*                                                                     */
/* Author: wikfors (later changes by degood)                           */
/*                                                                     */
/* MODULE PURPOSE: provide a 50hz task framework for handling various  */
/*                 run state activities and transitions.  Also provide */
/*                 a framework for activating the functions that live  */
/*                 at 50hz:  ramps, pneu_ctrl, time table, etc.        */
/*                                                                     */
/***********************************************************************/


/*****************************/
/*   GLOBAL INCLUDE FILES    */
/*****************************/


#include <typedefs.h>
#include <error.h>
#include <p_wkfile.h>
#include <wkfile.h>
#include <zone_config.h>
#include <ramps.h>
#include <zone_status.h>
#include <p_status.h>
#include <status.h>
#include <i_op.h>
#include <flow.h>
#include <keyboard.h>
#include <run_ui.h>
#include <valve.h>
#include <readiness.h>
#include <iomap.h>
#include <leds.h>
#include <exception.h>
#include <err_handler.h>
#include <sequence.h>
#include <seq_ui.h>
#include <timetable.h>
#include <sig_types.h>
#include <sigpath.h>
#include <glp.h>
#include <dig_path.h>
#include <p_ui.h>


/*****************************/
/*   LOCAL INCLUDE FILES     */
/*****************************/

#include "apg_bus.h"

/*****************************/
/*   GLOBAL VARIABLES        */
/*****************************/


/*****************************/
/*   EXTERNAL VARIABLES      */
/*****************************/

extern BIT8 Stepping;
extern BIT8 Go;
extern BIT8 Pcb_Cmd_Sent;

/*****************************/
/*   LOCAL DEFINES           */
/*****************************/


/*****************************/
/*   STATIC VARIABLES        */
/*****************************/


/*****************************/
/*   IMPLEMENT SECTION       */
/*****************************/

/***********************************************************************/
/* FUNCTION: RunTask                                                   */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: This is the ISR body for the 50 Hz interrupt.  The         */
/*          interrupt is generated when the 68331 pulse accumulator    */
/*          overflows from from FF -> 0.  PACNT is clocked at 8 kHz,   */
/*          so it takes 160 ticks, counting up from 96, before         */
/*          it rolls over and interrupts.                              */
/*                                                                     */
/* RETURNED VALUE: none                                                */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void RunTask ( void )

/**end_proto**/
{
     /* Handle start run transition. */
     if ( Start_Run_Pending )
     {
printf("in Start_Run_Pending\n");
           /*
           ** If we get a Start while we are in post time we have to reset initial values and ramps here,
           ** since the normal reset at the end of post time has not occurred.
           **
           ** We do this before disabling interrupts because it can take so long:  time reproducibility
           ** may suffer, but it is probably already messed up by the user aborting the post time!
           */
           if (Run_State == POST_RUN)
           {
                 SetInitValues();
           }

           INTERRUPTS_OFF

           Run_State = RUN_ACTIVE;
           Run_Requested = FALSE;  /* clear after Run_State changes */
           Pre_Run_Ready = FALSE;  /* clear after Run_State changes */
           Run_Clock = 0;
           Start_Run_Pending = FALSE;

           /* clear the GLP log */
           CLEAR_GLP_LOG();

           /* Disable run idle cryo blast behavior */
           Zone_Status.cryo_blast_allow = 0;

           /* reset warnings from the last run */
           /* don't reset during powerfail recovery so user has a chance to see them later */
           if (!Power_Fail_Blank_Run)
           {
                ClearWarnings();
           }

           /* reset the second channel datacomm buffer */
           ResetBufIfSingleMode();

           /* update the sample information for this run */
           SetSampleNumbers();

           /* perform pneumatics start run initialization */
           CheckInletReadinessAtStart();

           /* emit a start tick mark on the attenuator output */
           EMIT_ATTN_START_TICK();

           /* arm external start output:  the actual transition occurs below in ApgBusDriver() */
           AssertApgStart();

           if (!Scc_Run)
           {
                 /* init SCC data expansion in all non-SCC runs */
                 START_RUN_FOR_SCC_EXPAND();

                 /* increment run counter only for "real" runs (not SCC or blank runs) */
                 if (!Blank_Run)
                 {
                       Run_Count++;
                       /* Increment the esrvice counters */
                       /* Done this way for speed */
                       Service_Count[0]++;
                       Service_Count[1]++;
                       Service_Count[2]++;
                       Service_Count[3]++;
                       Service_Count[4]++;
                       Service_Count[5]++;
                       Service_Count[6]++;
                       Service_Count[7]++;
                 }
           }

           /* set LEDs */
//           TURN_PREP_RUN_LED_OFF();
//           TURN_RUN_LED_ON();
//           TURN_POST_RUN_LED_OFF();

           /* force re-evaluation of readiness after Run_State change */
           ClearNotReadyEval();

           INTERRUPTS_ON
     }

     /* update the APG bus:  if we just started a run this will drive remote start low */
     /* NOTE:  this should immediately follow the start run transition code to minimize skew */
     ApgBusDriver();

     /* Handle pre run waiting to pre run ready substate transition */
     INTERRUPTS_OFF
     if ( (Run_State == PRE_RUN) && !Pre_Run_Ready &&
          (InternalReadyForPrepRunEval() == READY) )
     {
           ClearNotReadyEval();         /* this state change affects pneu readiness, so force re-evaluation */
           Pre_Run_Ready = TRUE;
//           TURN_PREP_RUN_LED_ON();
     }
     INTERRUPTS_ON

     /* Handle SCC pre run to SCC run active state transition */
     if (( Scc_Run ) && ( Run_State == PRE_RUN ) && ( ReadyEval() == READY ))
     {
           SccRun();            /* all ready, let's go */
     }

     /* Handle blank pre run to blank run active state transition */
     if (( Blank_Run ) && ( Run_State == PRE_RUN ) && ( ReadyEval() == READY ))
     {
           (void) StartRun();   /* all ready, let's go */
     }

     /*
     ** Handle stop run transition.
     ** We insure here that a minimum run length is as long as the external start pulse duration,
     ** but no attempt is made to guarantee a minimum idle time between runs.
     */
     INTERRUPTS_OFF
     if ( Stop_Run_Pending && (Apg_Start_Pulse_Width <= 1) )
     {

           Run_State = POST_RUN;
           Last_Run_Time = Run_Clock;
           Run_Length = Next_Run_Length;
           Run_Clock = 0;
           Stop_Run_Pending = FALSE;

           if (Scc_Run)
           {
                   StopBlankRun();
           }
           else
           {
                   StopRunForScc();
           }

           /* signal stop to APG bus */
           AssertApgStop();

           /* mark signal path stop run */
           SetSigpathStopMarkers();

           /* undo run time programable values */
           UndoRunTableChanges();

           /* Allow run idle cryo blast behavior */
           Zone_Status.cryo_blast_allow = 0xff;

           /* make sure pressure readiness functions are in a normal state */
           ResetPresReadinessStates();

           /* begin auto recalibration of inlet flow sensors      */
           /* this is a multi second event that will be performed */
           /* by the gas task.  this call only triggers a request */
           RequestFlowSensorAutoZero();

//           TURN_PREP_RUN_LED_OFF();
//           TURN_POST_RUN_LED_ON();

           if (SequenceInProgress())
           {
                   /* blink run LED to indicate that unit is armed for an automated start */
//                   BLINK_RUN_LED();
           }
           else
           {
 //                  TURN_RUN_LED_OFF();
           }

           /* force re-evaluation of readiness after Run_State change */
           ClearNotReadyEval();

     }
     INTERRUPTS_ON

     /* calculate ramps */
     Ramps();

     /* update pneumatic display */
     if ( ! Inst_Config.Pneu.Dirt_Ball ) PneuDisplay();

     /* revisit, staged bringup, 512, pneu_init, real pneu */
     if ( Inst_Status.Pneu.Pneu_Alive )
     {
         if ( (!Stepping) || (( Stepping ) && ( Go )))
         {
            if (Inst_Config.Pneu.Dirt_Ball)  NonEpcPneuControl();
            else                             PneuControl();

            Go = FALSE;
            Pcb_Cmd_Sent = TRUE;
         }
     }

     SolenoidValveDrive();

     /* handle runtime activities */
     if ( Run_State == RUN_ACTIVE )
     {
         /* execute run table */
         ExecuteRunTimeTable();
     }

     /*
     ** Increment stopwatch timer at 50 Hz rate if it is enabled.
     ** Roll over to zero at 99:99.9.
     */
/*---------begin change by wangwei-------------------------*/
/*
     if (StopwatchRunning)
     {
        if (Stopwatch < 299999)
        {
           Stopwatch++;
        }
        else
        {
           Stopwatch = 0;
        }
     }
*/
/*---------------end change-----------------------------------*/

     /* Handle Multiport and GSV valve switching */
     ServiceGsvAndMultiValve();
}
